#include "Utility/Parsables/Entity.hpp"
#include "Common.hpp"
#include "Entity/IEntity.hpp"
#include "Graphics/Colour.hpp"
#include "Graphics/ISprite.hpp"
#include "Physics/IBody.hpp"
#include "Utility/EntityFactory.hpp"
#include "Utility/Parsables/IParsable.hpp"
#include "Utility/Singleton.hpp"
#include "Utility/String.hpp"

DefineParsable< Utility::Parsables::Entity > entityDef( "Entity" );

namespace Utility
{
	namespace Parsables
	{
		Entity::Entity( void )
		{
		}

		Entity::~Entity( void )
		{
		}

		void Entity::Create( void )
		{
			if ( !HasProperty( "class" ) )
			{
				//Report error: no class property

				return;
			}
			
			Property prop = GetProperty( "class" );
			::Entity::IEntity *ent = Singleton< EntityFactory >::Get()->Create( prop.str );

			//Entity/Shared features (pos, ang, size etc)
			
			if ( HasProperty( "size" ) )
			{
				prop = GetProperty( "size" );
				ent->SetSize( Vect( prop.obj ) );
			}

			if ( HasProperty( "position" ) )
			{
				prop = GetProperty( "position" );
				ent->SetPosition( Vect( prop.obj ) );
			}

			if ( HasProperty( "angle" ) )
			{
				prop = GetProperty( "angle" );
				ent->SetAngle( String::ConvertTo< float >( prop.str ) );
			}

			//Sprite features (image etc)
			Graphics::ISprite *spr = ent->GetSprite();

			if ( spr )
			{
				if ( HasProperty( "texture" ) )
				{
					prop = GetProperty( "texture" );
					spr->LoadImage( prop.str );
				}

				if ( HasProperty( "colour" ) )
				{
					prop = GetProperty( "colour" );

					Graphics::Colour col;
					col.r = String::ConvertTo< unsigned short >( prop.obj->GetProperty( "r" ).str );
					col.g = String::ConvertTo< unsigned short >( prop.obj->GetProperty( "g" ).str );
					col.b = String::ConvertTo< unsigned short >( prop.obj->GetProperty( "b" ).str );
					col.a = String::ConvertTo< unsigned short >( prop.obj->GetProperty( "a" ).str );

					spr->SetColour( col );
				}
			}

			//Physics features (mass etc)
			//Physics::IBody *phys = ent->GetPhysicsBody();
		}

		Math::Vectorf Entity::Vect( IParsable *obj )
		{
			Math::Vectorf vec;
			vec.x = String::ConvertTo< float >( obj->GetProperty( "x" ).str );
			vec.y = String::ConvertTo< float >( obj->GetProperty( "y" ).str );

			return vec;
		}
	}
}